package com.gusto.engine.clusterant.jmx;

import javax.management.Notification;

import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedOperation;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.jmx.export.notification.NotificationPublisher;
import org.springframework.jmx.export.notification.NotificationPublisherAware;

import com.gusto.engine.clusterant.algorithms.antsclustering.AntsClusteringAlgorithmListener;
import com.gusto.engine.clusterant.algorithms.antsclustering.Plan;
import com.gusto.engine.clusterant.algorithms.antsclustering.ants.Ant;
import com.gusto.engine.clusterant.algorithms.antsclustering.impl.RandomAntsClusteringAlgorithm;

/**
 * <p>MBean for managing AntsClustering.</p>
 * 
 * @author amokrane.belloui@gmail.com
 *
 */
@ManagedResource(objectName="gusto/clustering/ants:name=antsClustering", description="antsClustering", 
		         currencyTimeLimit=1, persistPolicy="OnUpdate", persistPeriod=200,
	             persistLocation="clustering", persistName="ants")
public class AntsClusteringMBean implements NotificationPublisherAware, AntsClusteringAlgorithmListener {
	
	private RandomAntsClusteringAlgorithm antsClusteringAlgorithm;
	private NotificationPublisher publisher;
	 
	public AntsClusteringMBean(RandomAntsClusteringAlgorithm antsClusteringAlgorithm) {
		super();
		this.antsClusteringAlgorithm = antsClusteringAlgorithm;
		this.antsClusteringAlgorithm.getListeners().add((AntsClusteringAlgorithmListener)this);
	}

	@ManagedAttribute(description="The number of active Ants", currencyTimeLimit=1)
	public Integer getActiveAntsCount() {
		return antsClusteringAlgorithm.getActiveAntsCount();
	}
	
	@ManagedAttribute(description="Total Time elapsed", currencyTimeLimit=1)
	public Long getTotalTime() {
		return antsClusteringAlgorithm.getTotalTime();
	}
	
	@ManagedAttribute(description="Number of moves done", currencyTimeLimit=1)
	public Long getTotalMovesDone() {
		return antsClusteringAlgorithm.getTotalMovesDone();
	}
	
	@ManagedAttribute(description="Number of moves left", currencyTimeLimit=1)
	public Long getTotalMovesLeft() {
		return antsClusteringAlgorithm.getTotalMovesLeft();
	}
	
	@ManagedOperation()
	public void addAnt() {
		antsClusteringAlgorithm.addAnt();
	}
	
	
	public void setNotificationPublisher(NotificationPublisher notificationPublisher) {
		this.publisher = notificationPublisher;
	}
	
	public void clusteringFinished(Plan plan) {
		this.publisher.sendNotification(new Notification("Clustering finished", this, 0));
	}
	
	public void antAdded(Ant ant) {
		this.publisher.sendNotification(new Notification("Adding a new Ant", this, 0));
	}
	
}
